<template>
  <svg
    :style="{ width: sizeRef + 'px', height: sizeRef + 'px' }"
    class="svg-icon"
    :class="{ spin: props.spin }"
  >
    <use
      :xlink:href="prefix + name"
      :fill="colorRef"
    />
  </svg>
</template>

<script setup lang="ts">
  import { computed } from "vue";

  defineOptions({
    name: "SvgIcon",
  });

  export type IconSize = "default" | "small" | "large";

  export type IconColor = "primary" | "default" | "success" | "warn" | "error";

  const props = withDefaults(
    defineProps<{
      /** icon 的前缀 */
      prefix?: string;
      /** icon 名称 */
      name: string;
      /** icon 的颜色 */
      color?: IconColor;
      /** icon 的尺寸 */
      size?: IconSize | number;
      spin?: boolean; // 旋转动画
    }>(),
    {
      prefix: "#icon-",
      size: "default",
      color: "default",
      spin: false,
    }
  );

  const sizeMap: Record<IconSize, number> = {
    default: 16,
    small: 12,
    large: 24,
  };

  const colorMap: Record<IconColor, string> = {
    primary: "#409EFF",
    success: "#67C23A",
    error: "#bb1b1b",
    warn: "#F56C6C",
    default: "#333333",
  };

  const colorRef = computed(() => {
    return colorMap[props.color] || props.color;
  });

  const sizeRef = computed(() => {
    if (typeof (props.size as IconSize) === "string") {
      return sizeMap[props.size as keyof typeof sizeMap] || sizeMap.default;
    }
    return props.size;
  });
</script>

<style scoped lang="less">
  .svg-icon {
    display: inline-block;

    &.spin {
      animation: rotating 3s infinite linear;
    }

    &:focus {
      outline: unset;
    }
  }
</style>
